package csel.view.area;

import java.awt.Graphics;
import java.awt.Point;
import csel.model.Decal;
import csel.model.Terrain;
import csel.model.TileVisitor;
import csel.model.Projectile;
import csel.model.areaeffect.AreaEffect;
import csel.model.entity.Entity;
import csel.model.items.Item;
import csel.view.ObjectRepresentor;
import csel.view.RepresentationFactory;

import java.util.*;
public class RenderVisitor implements TileVisitor
{
	private ObjectRepresentor objRep;
	private RepresentationFactory repFact;
	private Point p;
	private Positioner pos;
	private List<ObjectRepresentor> toDraw;

	/**
	 * Constructor
	 */
	public RenderVisitor(){
		repFact = RepresentationFactory.getInstance();
		pos = new Positioner();
		toDraw = new ArrayList<ObjectRepresentor>(1000);
	}
	
	/**
	 * Visits the terrain by getting the object representor for
	 * terrain, modifying the draw location and adding it to the toDraw list.
	 * @param terrain
	 */
	public void visitTerrain(Terrain terrain){
		objRep = repFact.get(terrain);
		objRep.drawPrep(p);
		toDraw.add(objRep);
	}
	
	/**
	 * Visits the Entity by getting the object representor for
	 * entity, modifying the draw location and adding it to the toDraw list.
	 * @param terrain
	 */
	public void visitEntity(Entity entity){
		objRep = repFact.get(entity);
		objRep.drawPrep(p);
		toDraw.add(objRep);
	}
	
	/**
	 * Visits the decal by getting the object representor for
	 * decal, modifying the draw location and adding it to the toDraw list.
	 * @param terrain
	 */
	public void visitDecal(Decal decal){
		objRep = repFact.get(decal);
		objRep.drawPrep(p);
		toDraw.add(objRep);
	}
	
	/**
	 * Visits the item by getting the object representor for
	 * item, modifying the draw location and adding it to the toDraw list.
	 * @param terrain
	 */
	public void visitItem(Item item){
		if(item.isVisible()){
			objRep = repFact.get(item);
			objRep.drawPrep(p);
			toDraw.add(objRep);
		}

	}
	
	public void visitProjectile(Projectile projectile)
	{
		objRep = repFact.get(projectile);
		objRep.drawPrep(p);
		toDraw.add(objRep);
	}
	
	/**
	 * Sets the point so objects will know where they will be drawn
	 * @param p
	 */
	public void setPoint(Point p){
		this.p = p;
	}
	
	/**
	 * Draws all objectRepresentors in toDraw to the graphics object given
	 * Clears the arrayList after use
	 * @param g
	 */
	public void drawAll(Graphics g)
	{
		for(ObjectRepresentor or : toDraw)
			or.drawCached(g);
		//clear the ObjRep list
		toDraw = new ArrayList<ObjectRepresentor>(1000);
	}

	public void visitAreaEffect(AreaEffect ae)
	{
		/* AreaEffects are not rendered */
	}
}
